﻿using ICSharpCode.AvalonEdit;
using Notifications.Wpf;
using System.IO;
using System.Text;
using System.Text.RegularExpressions;
using VideoTools.Extension;
using VideoTools.vo;

namespace VideoTools.Util
{
    public static class SubtitleUtils
    {
        public static List<Subtitle> AdjustSubtitleTiming(List<Subtitle> subtitles)
        {
            for (int i = 1; i < subtitles.Count; i++)
            {
                if (subtitles[i].StartTime != subtitles[i - 1].EndTime)
                {
                    //Console.WriteLine("end " + subtitles[i - 1].EndTime + "\t\t start " + subtitles[i].StartTime + (subtitles[i - 1].Text.Length > subtitles[i].Text.Length));
                    // 如果相邻两句字幕时间不连接，根据字幕文本长度调整时间轴
                    if (subtitles[i - 1].Text.Length > subtitles[i].Text.Length)
                    {
                        // 前一句字幕文本较多，调整前一句字幕的结束时间
                        subtitles[i - 1].EndTime = subtitles[i]
                            .StartTime.Subtract(new TimeSpan(0, 0, 0, 0, 1));
                    }
                    else
                    {
                        // 后一句字幕文本较多，调整后一句字幕的开始时间
                        //Console.WriteLine("end " + subtitles[i-1].EndTime + "\t" + subtitles[i - 1].EndTime.Add(new TimeSpan(0, 0, 0, 0, 1)));
                        subtitles[i].StartTime = subtitles[i - 1]
                            .EndTime.Add(new TimeSpan(0, 0, 0, 0, 1));
                    }
                }
            }
            for (int i = 0; i < subtitles.Count; i++)
            {
                subtitles[i].Number = i + 1;
            }

            return subtitles;
        }

        public static bool checkSub(TextEditor te)
        {
            List<string> txts = te.GetLines();
            var check = checkSubtitle(txts);
            SubTitleError error = check.error;
            int lineNumber = check.line;
            bool result = true;
            if (error != SubTitleError.OK)
            {
                result = false;
                var content = new NotificationContent()
                {
                    Title = "似乎字幕文件格式有点问题,原因",
                    Type = NotificationType.Error,
                    Message = error.Desc() + "\n行数:" + lineNumber,
                };
                AppManager.Instance.NotificationManager.Show(content);
                int lineCount = te.LineCount;
                if (lineNumber > 0 && lineNumber <= lineCount)
                {
                    te.GotoLineAndHightLight(lineNumber);
                }
            }
            return result;
        }


        private static Regex regex = new Regex("[\u4e00-\u9fa5]");

        public static bool isHasHz(string inputData)
        {
            Match m = regex.Match(inputData);
            return m.Success;
        }

        public static (bool hasHz, List<Subtitle> list) ReadSubtitle(List<string> txts)
        {
            List<Subtitle> subtitles = new List<Subtitle>();

            int subtitleNumber = 0;
            bool hasHz = false;
            for (int i = 0; i < txts.Count; i++)
            {
                if (int.TryParse(txts[i], out subtitleNumber))
                {
                    i++; // 跳过字幕编号
                    //Console.WriteLine($"line : {oldTxts[i]}");
                    string[] timeInfo = txts[i]
                        .Split(new char[] { '-', '-', '>' }, StringSplitOptions.RemoveEmptyEntries);

                    TimeSpan startTime;
                    TimeSpan endTime;

                    if (
                        TimeSpan.TryParseExact(
                            timeInfo[0].Trim(),
                            "hh\\:mm\\:ss\\,fff",
                            null,
                            out startTime
                        )
                        && TimeSpan.TryParseExact(
                            timeInfo[1].Trim(),
                            "hh\\:mm\\:ss\\,fff",
                            null,
                            out endTime
                        )
                    )
                    {
                        i++; // 跳过空行
                        string text = "";

                        // 读取字幕文本
                        while (i < txts.Count && !string.IsNullOrWhiteSpace(txts[i]))
                        {
                            text += txts[i] + "\n";
                            i++;
                        }
                        if (!hasHz)
                        {
                            hasHz = isHasHz(text);
                        }
                        subtitles.Add(
                            new Subtitle(subtitleNumber, startTime, endTime, text.Trim())
                        );
                    }
                }
            }
            return (hasHz, subtitles);
        }

        public static (SubTitleError error, int line,List<Subtitle> list) ReadSubtitle(TextEditor te)
        {
            List<string> txts = te.GetLines();
            var check = checkSubtitle(txts);
            SubTitleError error = check.error;
            int lineNumber = check.line;
            if (error != SubTitleError.OK)
            {
                var content = new NotificationContent()
                {
                    Title = "似乎字幕文件格式有点问题,原因",
                    Type = NotificationType.Error,
                    Message = error.Desc() + "\n行数:" + lineNumber,
                };
                AppManager.Instance.NotificationManager.Show(content);
                int lineCount = te.LineCount;
                if (lineNumber > 0 && lineNumber <= lineCount)
                {
                    te.GotoLineAndHightLight(lineNumber);
                }
                return (error,lineNumber,null);
            }
            var r = ReadSubtitle(txts);

            return (error,lineNumber,r.list);
        }
        /// <summary>
        /// 是否是字幕文件
        /// </summary>
        /// <param name="txt"></param>
        /// <returns></returns>
        public static (SubTitleError error, int line, List<Subtitle> subtitles) ReadAndCheckSubtitle(List<string> lines)
        {
            List<Subtitle> subtitles = new List<Subtitle>();

            int subtitleNumber = 0;
            try
            {
                // 检查文件是否为空
                if (lines == null || lines.Count == 0)
                {
                    return (SubTitleError.EmptyFile, -2,null);
                }

                // 检查每一行的格式
                for (int i = 0; i < lines.Count; i += 4)
                {
                    // 检查行号是否缺失
                    if (!int.TryParse(lines[i], out _))
                    {
                        return (SubTitleError.MissingLineNumber, i + 1,null);
                    }

                    // 检查时间格式是否正确
                    if (
                        !Regex.IsMatch(
                            lines[i + 1],
                            @"^\d{2}:\d{2}:\d{2},\d{3} \-\-> \d{2}:\d{2}:\d{2},\d{3}$"
                        )
                    )
                    {
                        return (SubTitleError.InvalidTimeFormat, i + 2,null);
                    }

        

                    // 检查字幕文本是否存在
                    if (string.IsNullOrWhiteSpace(lines[i + 2]))
                    {
                        return (SubTitleError.InvalidSubtitleText, i + 3, null);
                    }
                    // 检查字幕文本是否存在
                    if (!string.IsNullOrWhiteSpace(lines[i + 3]))
                    {
                        return (SubTitleError.EmptyLineIsNotEmpty, i + 4, null);
                    }

                    string[] timeInfo = lines[i + 2].Split(new char[] { '-', '-', '>' }, StringSplitOptions.RemoveEmptyEntries);

                    TimeSpan startTime;
                    TimeSpan endTime;
                    if (
                        TimeSpan.TryParseExact(
                            timeInfo[0].Trim(),
                            "hh\\:mm\\:ss\\,fff",
                            null,
                            out startTime
                        )
                        && TimeSpan.TryParseExact(
                            timeInfo[1].Trim(),
                            "hh\\:mm\\:ss\\,fff",
                            null,
                            out endTime
                        )
                    )
                    {
                        string text = "";

                        // 读取字幕文本
                        while (i < lines.Count && !string.IsNullOrWhiteSpace(lines[i]))
                        {
                            text += lines[i] + "\n";
                            i++;
                        }
                        subtitles.Add(
                            new Subtitle(subtitleNumber, startTime, endTime, text.Trim())
                        );
                    }
                }

                // 文件格式有效
                return (SubTitleError.OK,-1, subtitles);
            }
            catch (Exception ex)
            {
                System.Windows.Forms.MessageBox.Show(
                    "解析字幕文件异常,原因\n" + ex.Message,
                    "错误",
                    MessageBoxButtons.OK,
                    MessageBoxIcon.Error
                );
                return (SubTitleError.InvalidFormat, 0, null);
            }
        }
        /// <summary>
        /// 是否是字幕文件
        /// </summary>
        /// <param name="txt"></param>
        /// <returns></returns>
        public static (SubTitleError error, int line) checkSubtitle(List<string> lines)
        {
            try
            {
                // 检查文件是否为空
                if (lines == null || lines.Count == 0)
                {
                    return (SubTitleError.EmptyFile, -2);
                }

                // 检查每一行的格式
                for (int i = 0; i < lines.Count; i += 4)
                {
                    // 检查行号是否缺失
                    if (!int.TryParse(lines[i], out _))
                    {
                        return (SubTitleError.MissingLineNumber, i + 1);
                    }

                    // 检查时间格式是否正确
                    if (
                        !Regex.IsMatch(
                            lines[i + 1],
                            @"^\d{2}:\d{2}:\d{2},\d{3} \-\-> \d{2}:\d{2}:\d{2},\d{3}$"
                        )
                    )
                    {
                        return (SubTitleError.InvalidTimeFormat, i + 2);
                    }

                    // 检查字幕文本是否存在
                    if (string.IsNullOrWhiteSpace(lines[i + 2]))
                    {
                        return (SubTitleError.InvalidSubtitleText, i + 3);
                    }
                    // 检查字幕文本是否存在
                    if (!string.IsNullOrWhiteSpace(lines[i + 3]))
                    {
                        return (SubTitleError.EmptyLineIsNotEmpty, i + 4);
                    }
                }

                // 文件格式有效
                return (SubTitleError.OK, 0);
            }
            catch (Exception ex)
            {
                System.Windows.Forms.MessageBox.Show(
                    "解析字幕文件异常,原因\n" + ex.Message,
                    "错误",
                    MessageBoxButtons.OK,
                    MessageBoxIcon.Error
                );
                return (SubTitleError.InvalidFormat, 0);
            }
        }
        /// <summary>
        /// 读取双语字幕
        /// </summary>
        /// <param name="atxts"></param>
        /// <returns></returns>
        public static (List<Subtitle> subtitleList1, List<Subtitle> subtitleList2) ReadDueSubtitle(List<string> atxts)
        {
            List<Subtitle> subtitles1 = new List<Subtitle>();
            List<Subtitle> subtitles2 = new List<Subtitle>();

            int subtitleNumber = 0;
            for (int i = 0; i < atxts.Count; i++)
            {
                if (int.TryParse(atxts[i], out subtitleNumber))
                {
                    i++; // 跳过字幕编号
                    string[] timeInfo = atxts[i].Split(new char[] { '-', '-', '>' }, StringSplitOptions.RemoveEmptyEntries);

                    TimeSpan startTime;
                    TimeSpan endTime;

                    if (TimeSpan.TryParseExact(timeInfo[0].Trim(), "hh\\:mm\\:ss\\,fff", null, out startTime) &&
                     TimeSpan.TryParseExact(timeInfo[1].Trim(), "hh\\:mm\\:ss\\,fff", null, out endTime))
                    {
                        i++; // 跳过空行
                        List<string> textList = new List<string>();
                        // 读取字幕文本
                        while (i < atxts.Count && !string.IsNullOrWhiteSpace(atxts[i]))
                        {
                            textList.Add(atxts[i] + "\n");
                            i++;
                        }

                        subtitles1.Add(new Subtitle(subtitleNumber, startTime, endTime, textList[0].Trim()));
                        subtitles2.Add(new Subtitle(subtitleNumber, startTime, endTime, textList[1].Trim()));
                    }
                }
            }
            return (subtitles1,subtitles2);
        }

        public static  List<SubtitleDue> readMultSubtitleFile(string path)
        {
            if (File.Exists(path))
            {
                try
                {
                    List<string> lines = new List<string>();
                    // 创建一个 StreamReader 的实例来读取文件 
                    // using 语句也能关闭 StreamReader
                    using (StreamReader sr = new StreamReader(path))
                    {
                        while (!sr.EndOfStream)
                        {
                            string line = sr.ReadLine();
                            lines.Add(line);
                        }
                    }
                    List<SubtitleDue> subs = new List<SubtitleDue>();
                    int subtitleNumber = 0;
                    for (int i = 0; i < lines.Count; i++)
                    {
                        if (int.TryParse(lines[i], out subtitleNumber))
                        {
                            i++; // 跳过字幕编号
                                 //Console.WriteLine($"line : {oldTxts[i]}");
                            string[] timeInfo = lines[i].Split(new char[] { '-', '-', '>' }, StringSplitOptions.RemoveEmptyEntries);

                            TimeSpan startTime;
                            TimeSpan endTime;

                            if (TimeSpan.TryParseExact(timeInfo[0].Trim(), "hh\\:mm\\:ss\\,fff", null, out startTime) &&
                             TimeSpan.TryParseExact(timeInfo[1].Trim(), "hh\\:mm\\:ss\\,fff", null, out endTime))
                            {
                                i++; // 跳过空行
                                string text = "";
                                string text1 = "";

                                text += lines[i] + "\n";
                                i++;
                                text1 += lines[i] + "\n";
                                i++;
                                subs.Add(new SubtitleDue(subtitleNumber, startTime, endTime, text.Trim(), text1.Trim()));
                            }
                        }
                    }
                    return subs;
                }
                catch (Exception err)
                {
                    Console.WriteLine(err.Message);
                    return null;
                }
            }
            return null;
        }

        /// <summary>
        /// 是否是双语字幕文件
        /// </summary>
        /// <param name="txt"></param>
        /// <returns></returns>
        public static (SubTitleError error, int line) checkSubtitleDue(List<string> lines)
        {
            try
            {
                //Console.WriteLine("lines null ? " + (lines == null));
                //Console.WriteLine("lines count ? " + lines.Count);
                // 检查文件是否为空
                if (lines == null || lines.Count == 0)
                {
                    return (SubTitleError.EmptyFile, -2);
                }

                // 检查每一行的格式
                for (int i = 0; i < lines.Count; i += 5)
                {
                    // 检查行号是否缺失
                    if (!int.TryParse(lines[i], out _))
                    {
                        return (SubTitleError.MissingLineNumber, i + 1);
                    }

                    // 检查时间格式是否正确
                    if (
                        !Regex.IsMatch(
                            lines[i + 1],
                            @"^\d{2}:\d{2}:\d{2},\d{3} \-\-> \d{2}:\d{2}:\d{2},\d{3}$"
                        )
                    )
                    {
                        return (SubTitleError.InvalidTimeFormat, i + 2);
                    }

                    // 检查字幕文本是否存在
                    if (string.IsNullOrWhiteSpace(lines[i + 2]))
                    {
                        return (SubTitleError.InvalidSubtitleText, i + 3);
                    }
                    // 检查字幕文本是否存在
                    if (string.IsNullOrWhiteSpace(lines[i + 3]))
                    {
                        return (SubTitleError.InvalidSubtitleText, i + 4);
                    }
                }

                // 文件格式有效
                return (SubTitleError.OK, 0);
            }
            catch (Exception ex)
            {
                System.Windows.Forms.MessageBox.Show(
                    "解析双语字幕文件异常,原因\n" + ex.Message,
                    "错误",
                    MessageBoxButtons.OK,
                    MessageBoxIcon.Error
                );
                return (SubTitleError.InvalidFormat, 0);
            }
        }

        public static List<Subtitle> ReadSubtitle(string fileInfo)
        {
            return ReadSubtitle(new FileInfo(fileInfo));
        }

        /// <summary>
        /// 超强纠错解析字幕文件
        /// </summary>
        /// <param name="fileInfo"></param>
        /// <returns></returns>
        public static List<Subtitle> ReadSubtitle(FileInfo fileInfo)
        {
            List<Subtitle> subtitles = new List<Subtitle>();
            string line;
            using (FileStream fs = new FileStream(fileInfo.FullName, FileMode.Open))
            {
                using (StreamReader sr = new StreamReader(fs, Encoding.Default))
                {
                    StringBuilder sb = new StringBuilder();
                    int numb = 1;
                    int lineNo = 0;
                    while ((line = sr.ReadLine()) != null)
                    {
                        //Log.Information("line " + line);
                        if (!line.Equals(""))
                        {
                            sb.Append(line).Append("@");
                            continue;
                        }
                        string[] parseStrs = sb.ToString().Split('@');
                        if (parseStrs.Length < 3)
                        {
                            sb.Remove(0, sb.Length); // 清空，否则影响下一个字幕元素的解析</i>
                            continue;
                        }
                        string strToTime = parseStrs[1];
                        string[] timeInfo = strToTime.Split(
                            new char[] { '-', '-', '>' },
                            StringSplitOptions.RemoveEmptyEntries
                        );
                        TimeSpan startTime;
                        TimeSpan endTime;
                        try
                        {
                            TimeSpan.TryParseExact(
                                timeInfo[0].Trim(),
                                "hh\\:mm\\:ss\\,fff",
                                null,
                                out startTime
                            );
                            TimeSpan.TryParseExact(
                                timeInfo[1].Trim(),
                                "hh\\:mm\\:ss\\,fff",
                                null,
                                out endTime
                            );
                        }
                        catch (Exception exc)
                        {
                            System.Windows.Forms.MessageBox.Show(
                                "异常了" + fileInfo.FullName + "\n行" + lineNo
                            );
                            return null;
                        }
                        string strBody = null;
                        for (int i = 2; i < parseStrs.Length; i++)
                        {
                            strBody += parseStrs[i] + " ";
                        }

                        subtitles.Add(new Subtitle(numb++, startTime, endTime, strBody.Trim()));
                        sb.Remove(0, sb.Length);
                        lineNo += 4;
                    }
                }
            }
            return subtitles;
        }

        public static List<Subtitle> MergeSubtitle(
            List<Subtitle> subtitle1,
            List<Subtitle> subtitle2
        )
        {
            List<Subtitle> mergedSubtitles = new List<Subtitle>();

            for (int i = 0; i < Math.Min(subtitle1.Count, subtitle2.Count); i++)
            {
                Subtitle sub1 = subtitle1[i];
                Subtitle sub2 = subtitle2[i];

                // Assuming the timecodes match
                if (sub1.StartTime == sub2.StartTime && sub1.EndTime == sub2.EndTime)
                {
                    Subtitle mergedSubtitle = new Subtitle(
                        sub1.Number,
                        sub1.StartTime,
                        sub1.EndTime,
                        $"{sub1.Text}{Environment.NewLine}{sub2.Text}"
                    );
                    //mergedSubtitle.Text = $"{sub1.Text}\n{sub2.Text}";
                    mergedSubtitles.Add(mergedSubtitle);
                }
                else
                {
                    // Handle mismatched timecodes or other issues
                    // You may want to implement additional logic based on your specific needs
                }
            }

            return mergedSubtitles;
        }

        /// <summary>
        /// 导出是字幕文本
        /// </summary>
        /// <param name="txt"></param>
        /// <returns></returns>
        public static List<string> exportSubTitleText(List<string> lines)
        {
            List<string> textList = new List<string>();
            try
            {
                //Console.WriteLine("lines null ? " + (lines == null));
                //Console.WriteLine("lines count ? " + lines.Count);
                // 检查文件是否为空
                if (lines == null || lines.Count == 0)
                {
                    return null;
                }

                // 检查每一行的格式
                for (int i = 0; i < lines.Count; i += 4)
                {
                    // 检查行号是否缺失
                    if (!int.TryParse(lines[i], out _))
                    {
                        return null;
                    }

                    // 检查时间格式是否正确
                    if (
                        !Regex.IsMatch(
                            lines[i + 1],
                            @"^\d{2}:\d{2}:\d{2},\d{3} \-\-> \d{2}:\d{2}:\d{2},\d{3}$"
                        )
                    )
                    {
                        return null;
                    }

                    // 检查字幕文本是否存在
                    if (string.IsNullOrWhiteSpace(lines[i + 2]))
                    {
                        return null;
                    }
                    else
                    {
                        textList.Add(lines[i + 2]);
                    }
                }

                // 文件格式有效
                return textList;
            }
            catch (Exception ex)
            {
                System.Windows.Forms.MessageBox.Show(
                    "解析字幕文件异常,原因\n" + ex.Message,
                    "错误",
                    MessageBoxButtons.OK,
                    MessageBoxIcon.Error
                );
                return null;
            }
        }
    }
}
